package com.robosense.datacenter.dynamic.config;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.robosense.datacenter.dynamic.datasource.DBTypeEnum;
import com.robosense.datacenter.dynamic.datasource.DynamicDataSource;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

/**
 * Mybatis Plus 配置
 */
@Configuration
@MapperScan({"com.robosense.datacenter.mapper"})
public class MybatisPlusConfig {

    //mybatis-plus分页插件
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        //paginationInterceptor.setLocalPage(true);// 开启 PageHelper 的支持
        return paginationInterceptor;
    }

    //mybatis-plus SQL执行效率插件【生产环境可以关闭】
    @Bean
    public PerformanceInterceptor performanceInterceptor() {
        return new PerformanceInterceptor();
    }

    @Autowired
    Environment environment;
    @Value("${spring.datasource.druid.center.url}")
    private String datasourceUrl;
    @Value("${spring.datasource.druid.center.username}")
    private String username;
    @Value("${spring.datasource.druid.center.password}")
    private String password;
    @Value("${spring.datasource.druid.center.driver-class-name}")
    private String driverClassName;
    @Value("${spring.jackson.time-zone}")
    private String timeZoneValue;
    @Value("${spring.jackson.custom-time-zone}")
    private String customTimeZone;

    private HikariDataSource initDataSource() {
        HikariDataSource datasource = new HikariDataSource();
        datasource.setJdbcUrl(datasourceUrl);
        datasource.setUsername(username);
        datasource.setPassword(password);
        datasource.setDriverClassName(driverClassName);
        try {
            //jdbc:mysql://localhost:3306/data_center?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
            Class.forName(driverClassName);
            //jdbc:mysql://localhost:3306/data_center
            String url01 = datasourceUrl.substring(0, datasourceUrl.indexOf("?"));
            //jdbc:mysql://localhost:3306
            String url02 = url01.substring(0, url01.lastIndexOf("/"));
            //data_center
            String datasourceName = url01.substring(url01.lastIndexOf("/") + 1);
            // 连接已经存在的数据库，如：mysql
            System.out.println("==="+url02.concat(customTimeZone)+"="+username+"="+password);
            Connection connection = DriverManager.getConnection(url02.concat(customTimeZone), username, password);
            Statement statement = connection.createStatement();
            // 创建数据库
            statement.executeUpdate("create database if not exists `" + datasourceName + "` default character set utf8 COLLATE utf8_general_ci");
            statement.close();
            connection.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return datasource;
    }


    @Bean(name = "center")
    @ConfigurationProperties(prefix = "spring.datasource.druid.center")
    public DataSource center() {
        DataSource build = initDataSource();
        if (build == null) {
            build = DataSourceBuilder.create().build();
        }
        return build;
    }

    @Bean(name = "guard")
    @ConfigurationProperties(prefix = "spring.datasource.druid.guard")
    public DataSource guard() {
        return DruidDataSourceBuilder.create().build();
    }

    // 动态数据源配置
    @Bean
    @Primary
    public DataSource multipleDataSource(@Qualifier("center") DataSource center,
                                         @Qualifier("guard") DataSource guard) {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DBTypeEnum.center.getValue(), center);
        targetDataSources.put(DBTypeEnum.guard.getValue(), guard);
        dynamicDataSource.setTargetDataSources(targetDataSources);
        dynamicDataSource.setDefaultTargetDataSource(center);
        return dynamicDataSource;
    }

    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(multipleDataSource(center(), guard()));
        sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath*:mapper/*/*.xml"));
//        sqlSessionFactory.setTypeAliasesPackage("com.robosense.datacenter.bean");
        MybatisConfiguration configuration = new MybatisConfiguration();
        //configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
        configuration.setJdbcTypeForNull(JdbcType.NULL);
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setCacheEnabled(false);
        sqlSessionFactory.setConfiguration(configuration);
        sqlSessionFactory.setPlugins(new Interceptor[]{ //PerformanceInterceptor(),OptimisticLockerInterceptor()
                paginationInterceptor()
        });
        return sqlSessionFactory.getObject();
    }
}
